package com.seed.core;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.seed.commons.dbquery.BaseQuery;
import com.seed.commons.dbquery.PageModel;
import com.seed.commons.exception.SystemException;

@SuppressWarnings("unchecked")
public class HibernateDAOSupport<T> extends HibernateTemplateUtil<T> implements HibernateDAO<T> {

	public void saveEntity(T entity) throws RuntimeException {
		this.getHibernateTemplate().save(entity) ;
	}

	public T saveEnity(T entity) throws RuntimeException {
		return (T) this.getHibernateTemplate().save(entity) ;
	}

	public void delRow(Serializable id) throws RuntimeException {
		this.getHibernateTemplate().delete(id) ;
	}

	public void delRows(final Class<T> entityClass,final Serializable[] ids) throws RuntimeException {
		this.getHibernateTemplate().execute(new HibernateCallback() {
			
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				if(null != ids && ids.length > 0) {
					
					for(int i=0; i<ids.length; i++) {
						session.delete(session.get(entityClass, ids[i]));
					}
				}
				return null;
			}
		}) ;
	}

	public void updateEntity(T entity) throws RuntimeException {
		this.getHibernateTemplate().update(entity) ;
	}

	public T getEntity(Class<T> entityClass,Serializable id) throws RuntimeException {
		
		return (T) this.getHibernateTemplate().get(entityClass, id);
	}

	public T getEntityByParam(String queryString, String whereString,
			Object[] param) throws RuntimeException {
		
		
		
		return null;
	}

	public T loadEntity(Class<T> entityClass,Serializable id) throws RuntimeException {
		
		return (T) this.getHibernateTemplate().load(entityClass, id);
	}

	public T loadEntityByParam(String queryString, String whereString,
			LinkedHashMap<String, String> orderby, Object[] param)
			throws RuntimeException {
		
		return null;
	}

	public List<T> findEntity(String queryString, String whereString,
			LinkedHashMap<String, String> orderby, Object[] param)
			throws RuntimeException {
		
		return null;
	}

	public PageModel<T> getScrollRecord(final String queryString, final String whereString,
			final LinkedHashMap<String, String> orderby, int startPage, int endPage,
			final Object[] param) throws RuntimeException {
		
		return (PageModel<T>) this.getHibernateTemplate().execute(new HibernateCallback() {
			
			public Object doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query = session.createQuery(queryString + buildWhereString(whereString) + buildOrderByString(orderby)) ;
				
				setQueryParameter(query, param) ;
				
				PageModel<T> pm = new PageModel<T>() ;
				pm.setResultList(query.list()) ;
				pm.setTotalRecord(getRecordTotal(session,queryString,whereString,param)) ;
				
				return pm;
			}
		}) ;
	}
	/**
	 * 设置查询条件
	 * @param whereString
	 * @return
	 */
	protected static String buildWhereString(String whereString) {
		return null != whereString && !"".equals(whereString.trim()) ? BaseQuery.WHERE + whereString : "" ; 
	}
	/** 设置检索参数 */
	protected static void setQueryParameter(Query query,Object ...param) {
		if(null != param && param.length > 0) {
			for(int i=0; i<param.length; i++) {
				query.setParameter(i, param[i]) ;
			}
		}
	}
	
	/**
	 * 设置排序语句
	 * @param orderby
	 * @return
	 */
	protected static String buildOrderByString(LinkedHashMap<String, String> orderby) {
		StringBuffer bufStr = null;

		if (null != orderby && orderby.size() > 0) {
			bufStr = new StringBuffer();
			bufStr.append(BaseQuery.ORDERBY) ;
			for (String key : orderby.keySet()) {
				bufStr.append("o.").append(key).append(" ").append(orderby.get(key)).append(",");
			}
			bufStr.deleteCharAt(bufStr.length() - 1);

			return bufStr.toString();
		} else {
			return "";
		}
	}
	
	/**
	 * 获得统计查询记录
	 * @param session 会话
	 * @param queryString 查询语句
	 * @param whereString 条件语句
	 * @param param 查询参数
	 * @return long类型
	 */
	protected static long getRecordTotal(Session session,String queryString,String whereString,Object[] param) {
		Query query = session.createQuery(getCountQueryString(queryString) + buildWhereString(whereString));
		setQueryParameter(query, param) ;
		return (Long)query.uniqueResult() ;
	}
	
	/**
	 * 拼装统计查询语句
	 * @param queryString
	 * @return
	 */
	protected static String getCountQueryString(String queryString) {
		int index = queryString.indexOf("from") ;
		if(index != -1) {
			return "select count(o) " + queryString.substring(index) ;
		}
		throw new SystemException("拼装统计查询语句出错...") ;
	}
	
	

}
